package com.wing.product.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wing.common.exception.BusinessException;
import com.wing.common.utils.JsonResult;
import com.wing.dict.model.entity.DictLabel;
import com.wing.dict.service.DictLabelService;
import com.wing.product.dao.ProductTypeDao;
import com.wing.product.model.entity.ProductDetail;
import com.wing.product.model.entity.ProductType;
import com.wing.product.model.request.ProductTypeForm;
import com.wing.product.model.response.*;
import com.wing.sell.model.response.NodeDataVO;
import com.wing.user.feign.UserClient;
import com.wing.user.model.request.Role;
import com.wing.web.excel.ProductTypeExcelIn;
import com.wing.web.excel.UserExcelIn;
import com.wing.web.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

/**
 * 产品类型-ServiceImpl
 *
 * @author
 */
@Service
@Slf4j
public class ProductTypeServiceImpl extends ServiceImpl<ProductTypeDao, ProductType> implements ProductTypeService {

    @Autowired
    private DictLabelService dictLabelService;

    @Autowired
    private UserClient userClient;

    @Autowired
    private ProductUnitService productUnitService;

    @Autowired
    private ProductSpecService productSpecService;

    @Autowired
    private ProductAttributeService productAttributeService;

    @Autowired
    private ProductItemService productItemService;

    @Override
    public int add(ProductTypeForm productTypeForm) {
        //校验
        ProductType productType = new ProductType();
        CopyOptions copyOptions = CopyOptions.create().setEditable(ProductType.class).setIgnoreError(true).setIgnoreNullValue(true);
        BeanUtil.copyProperties(productTypeForm, productType, copyOptions);
        String code = getCode();
//        productType.setCode("M" + code);
        productType.setNo(Integer.valueOf(code));
        return baseMapper.insert(productType);
    }

    private String getCode() {
        String code = "";
        Integer maxNo = baseMapper.getMaxNo();
        if (maxNo == null) {
            maxNo = 1;
        } else {
            maxNo += 1;
        }
        for (int i = 0; i < 4 - maxNo.toString().length(); i++) {
            code += "0";
        }
        return code + maxNo.toString();
    }

    @Override
    public List<ProductTypeVO> list4app(Map<String, Object> params) {
        return baseMapper.list4app(params);
    }

    @Override
    public Page<ProductTypeVO> pageList4app(Page page, Map<String, Object> params) {
        List<ProductTypeVO> list = baseMapper.list4app(page, params);
        page.setRecords(list);
        return page;
    }

    @Override
    public ProductTypeVO get4appById(Long id) {
        ProductTypeVO productTypeVO = baseMapper.get4appById(id);
        if (ObjectUtil.isEmpty(productTypeVO)){
            return null;
        }
        //计量单位列表
        Map<String,Object> productTypeMap = new HashMap();
        productTypeMap.put("productType", id);
        List<ProductUnitInfoVO> productUnitList = productUnitService.list4app(productTypeMap);
        productTypeVO.setProductUnitList(productUnitList);
        //规格列表
        Map<String,Object> productSpecMap = new HashMap();
        productSpecMap.put("productType", id);
        List<ProductSpecVO> productSpecList = productSpecService.list4app(productSpecMap);
        productTypeVO.setProductSpecList(productSpecList);
        //属性列表
        Map<String,Object> productAttributeMap = new HashMap();
        productAttributeMap.put("productType", id);
        List<ProductAttributeVO> productAttributeList = productAttributeService.list4app(productAttributeMap);
        productTypeVO.setProductAttributeList(productAttributeList);
        //检测项列表
        Map<String,Object> productItemMap = new HashMap();
        productItemMap.put("productType", id);
        List<ProductItemVO> productItemList = productItemService.list4app(productItemMap);
        productTypeVO.setProductItemList(productItemList);

        return productTypeVO;
    }

    public JsonResult getTreeData(Long productTypeId, List<Long> materialNatureList) {
        List<Long> productTypeIdList = new ArrayList<>();
        if (productTypeId != null) {
            productTypeIdList = this.baseMapper.getProductTypeHierarchy(productTypeId);
        }
        QueryWrapper<ProductType> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("final_classify_status", 1);
        if (productTypeId != null) {
            queryWrapper.notIn("id", productTypeIdList);
        }
        if(materialNatureList != null && !materialNatureList.isEmpty() && materialNatureList.size() > 0){
            queryWrapper.in("material_nature", materialNatureList);
        }

        List<ProductType> list = this.baseMapper.selectList(queryWrapper);
        Map<Long, List<NodeDataVO>> map = new HashMap<>();
        for (ProductType productType : list) {
            if (map.containsKey(productType.getParentId())) {
                NodeDataVO nodeDataVO = new NodeDataVO();
                nodeDataVO.setValue(productType.getId().toString());
                nodeDataVO.setName(productType.getName());
                nodeDataVO.setPid(productType.getParentId().toString());
                map.get(productType.getParentId()).add(nodeDataVO);
            } else {
                List<NodeDataVO> tmpList = new ArrayList<>();
                NodeDataVO nodeDataVO = new NodeDataVO();
                nodeDataVO.setValue(productType.getId().toString());
                nodeDataVO.setName(productType.getName());
                nodeDataVO.setPid(productType.getParentId().toString());
                tmpList.add(nodeDataVO);
                map.put(productType.getParentId(), tmpList);
            }
        }
        List<NodeDataVO> rootList = map.get(-1L);
        if (rootList == null) {
            return JsonResult.success();
        }
        constructTree(rootList, map);
        return JsonResult.success(rootList);
    }

    public JsonResult getTreeDataForLast(Long productTypeId, List<Long> materialNatureList) {
        List<Long> productTypeIdList = new ArrayList<>();
        if (productTypeId != null) {
            productTypeIdList = this.baseMapper.getProductTypeHierarchy(productTypeId);
        }
        QueryWrapper<ProductType> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("final_classify_status", 1);
        if (productTypeId != null) {
            queryWrapper.notIn("id", productTypeIdList);
        }
        if(materialNatureList != null && !materialNatureList.isEmpty() && materialNatureList.size() > 0){
            queryWrapper.in("material_nature", materialNatureList);
        }

        List<ProductType> list = this.baseMapper.selectList(queryWrapper);
        Map<Long, List<NodeDataVO>> map = new HashMap<>();
        for (ProductType productType : list) {
            if (map.containsKey(productType.getParentId())) {
                NodeDataVO nodeDataVO = new NodeDataVO();
                nodeDataVO.setValue(productType.getId().toString());
                nodeDataVO.setName(productType.getName());
                nodeDataVO.setPid(productType.getParentId().toString());
                if(productType.getFinalClassifyStatus() == 1){
                    nodeDataVO.setDisabled(true);
                }
                map.get(productType.getParentId()).add(nodeDataVO);
            } else {
                List<NodeDataVO> tmpList = new ArrayList<>();
                NodeDataVO nodeDataVO = new NodeDataVO();
                nodeDataVO.setValue(productType.getId().toString());
                nodeDataVO.setName(productType.getName());
                nodeDataVO.setPid(productType.getParentId().toString());
                if(productType.getFinalClassifyStatus() == 1){
                    nodeDataVO.setDisabled(true);
                }
                tmpList.add(nodeDataVO);
                map.put(productType.getParentId(), tmpList);
            }
        }
        List<NodeDataVO> rootList = map.get(-1L);
        if (rootList == null) {
            return JsonResult.success();
        }
        constructTree(rootList, map);
        return JsonResult.success(rootList);
    }

    private void constructTree(List<NodeDataVO> parentList, Map<Long, List<NodeDataVO>> dataMap) {
        for (NodeDataVO node : parentList) {
            Long nodeId = Long.valueOf(node.getValue());
            List<NodeDataVO> childList = dataMap.get(nodeId);
            if (childList != null) {
                node.setChildren(childList);
                constructTree(childList, dataMap);
            }
        }
    }

    @Override
    public void importExcel(List<ProductTypeExcelIn> list) {
        List<ProductType> productTypeList = new ArrayList<>();
        //上级类别列表
        List<ProductType> parentProductTypeList = this.baseMapper.selectList(null);
        //类别性质
        QueryWrapper<DictLabel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("dict_type", "sys_product_type_nature");
        List<DictLabel> dictLabelList = dictLabelService.list(queryWrapper);
        //维护部门
        List<Role> roleList = userClient.getRoleDepartment();

        int i = 1;
        for (ProductTypeExcelIn item : list) {
            if(StringUtils.isBlank(item.getCode())){
                throw new BusinessException(300, "第"+i+"行类别编码未输入数据");
            }
            if(StringUtils.isBlank(item.getName())){
                throw new BusinessException(300, "第"+i+"行类别名称未输入数据");
            }
            if(StringUtils.isBlank(item.getFinalClassifyName())){
                throw new BusinessException(300, "第"+i+"行是否终极分类未输入数据");
            }
            if(StringUtils.isBlank(item.getThingCodeName())){
                throw new BusinessException(300, "第"+i+"行是否一物一码未输入数据");
            }
            if(StringUtils.isBlank(item.getGuaranteeName())){
                throw new BusinessException(300, "第"+i+"行是否有质保期未输入数据");
            }
            if(StringUtils.isBlank(item.getInoutName())){
                throw new BusinessException(300, "第"+i+"行是否先进先出未输入数据");
            }
            if(StringUtils.isBlank(item.getMaterialNatureName())){
                throw new BusinessException(300, "第"+i+"行类别性质未输入数据");
            }
            if(StringUtils.isBlank(item.getTypeServiceDepartmentName())){
                throw new BusinessException(300, "第"+i+"行类别维护部门未输入数据");
            }
            i++;

            //判断名称是否存在
            ProductType productType0 = parentProductTypeList.stream().filter(t->t.getName().equals(item.getName())).findFirst().orElse(null);
            if(productType0 != null){
                throw new BusinessException(300, "类别名称["+item.getName()+"]已存在");
            }
            //新增
            ProductType productType = new ProductType();
            productType.setCode(item.getCode());
            productType.setName(item.getName());
            String code = getCode();
            productType.setNo(Integer.valueOf(code));
            if(StringUtils.isNotEmpty(item.getParentName())){
                ProductType parentProductType = parentProductTypeList.stream().filter(t->t.getName().equals(item.getParentName())).findFirst().orElse(null);
                if(parentProductType != null){
                    productType.setParentId(parentProductType.getId());
                }
            }
            //是否终极分类
            if(item.getFinalClassifyName().equals("是")){
                productType.setFinalClassifyStatus(0);
            }else{
                productType.setFinalClassifyStatus(1);
            }
            //是否一物一码
            if(item.getThingCodeName().equals("是")){
                productType.setThingCodeStatus(0);
            }else{
                productType.setThingCodeStatus(1);
            }
            //是否有质保期
            if(item.getGuaranteeName().equals("是")){
                productType.setGuaranteeStatus(0);
            }else{
                productType.setGuaranteeStatus(1);
            }
            //是否先进先出
            if(item.getInoutName().equals("是")){
                productType.setInoutStatus(0);
            }else{
                productType.setInoutStatus(1);
            }
            //类别性质
            DictLabel dictLabel = dictLabelList.stream().filter(t->t.getLabelName().equals(item.getMaterialNatureName())).findFirst().orElse(null);
            productType.setMaterialNature(Integer.valueOf(dictLabel.getLabelValue()));
            //类别维护部门
            Role roleDepartment = roleList.stream().filter(t->t.getName().equals(item.getTypeServiceDepartmentName())).findFirst().orElse(null);
            productType.setTypeServiceDepartment(roleDepartment.getId());
            //排序
            productType.setSortNumber(Integer.valueOf(item.getSort()));
            productType.setType("0");
            productType.setDataSourceType(ProductType.DataSourceType.enterprise);
            productType.setLimitWeight(false);
            productType.setLimitSize(false);
            productType.setHasUseBox(false);
            productType.setCabCutterType(false);
            productType.setCreator(JwtUtils.getLoginUserId());
            productType.setCreatorName(JwtUtils.getUsername());
            productType.setCreateTime(LocalDateTime.now());
            productType.setIsDeleted(true);
            productTypeList.add(productType);
        }
        this.saveBatch(productTypeList);
    }

    @Override
    public Integer getProductTypeCount(Long productTypeId) {
        return this.baseMapper.getProductTypeCount(productTypeId);
    }

    /**
     * 获取所有的
     * @param productTypeId
     * @param materialNatureList
     * @return
     */
    @Override
    public JsonResult getAllTreeData(Long productTypeId, List<Long> materialNatureList) {
        List<Long> productTypeIdList = new ArrayList<>();
        if (productTypeId != null) {
            productTypeIdList = this.baseMapper.getProductTypeHierarchy(productTypeId);
        }
        QueryWrapper<ProductType> queryWrapper = new QueryWrapper<>();
        if (productTypeId != null) {
            queryWrapper.notIn("id", productTypeIdList);
        }
        if(materialNatureList != null && !materialNatureList.isEmpty() && materialNatureList.size() > 0){
            queryWrapper.in("material_nature", materialNatureList);
        }

        List<ProductType> list = this.baseMapper.selectList(queryWrapper);
        Map<Long, List<NodeDataVO>> map = new HashMap<>();
        for (ProductType productType : list) {
            if (map.containsKey(productType.getParentId())) {
                NodeDataVO nodeDataVO = new NodeDataVO();
                nodeDataVO.setValue(productType.getId().toString());
                nodeDataVO.setName(productType.getName());
                nodeDataVO.setPid(productType.getParentId().toString());
                map.get(productType.getParentId()).add(nodeDataVO);
            } else {
                List<NodeDataVO> tmpList = new ArrayList<>();
                NodeDataVO nodeDataVO = new NodeDataVO();
                nodeDataVO.setValue(productType.getId().toString());
                nodeDataVO.setName(productType.getName());
                nodeDataVO.setPid(productType.getParentId().toString());
                tmpList.add(nodeDataVO);
                map.put(productType.getParentId(), tmpList);
            }
        }
        List<NodeDataVO> rootList = map.get(-1L);
        if (rootList == null) {
            return JsonResult.success();
        }
        constructTree(rootList, map);
        return JsonResult.success(rootList);
    }

    /**
     * 查询类型信息 连带基础单位信息
     * @return
     */
    @Override
    public List<ProductType> listAndSelectBaseUnit() {
        return baseMapper.listAndSelectBaseUnit();
    }

}
